
from fg import run

class Tex: # test-exit
  def __lt__(_, code):
    run(code, debug_max=20000)
    # ~ run(code, debug_max=-1) # 只打印最终栈结果
    exit()

  def __truediv__(self, code):
      self < code

  def __floordiv__(_, __):
    pass
tex = Tex()

# tex /  "...." 可以运行代码并退出
# 可以通过改成 tex // "..." 来不运行它

def main():
    # ~ pass
    # ~ print(len(div8))
    # ~ print(div8)
    tex / f'f f 0 3 {div8}'     # 计算16进制的12/2



# 申请n byte空间
tex // """
[
    [0 over]
    [
      0
      0 swap
      1 -
    ]
    while-do
    drop
]
1 2
3
3 over call
"""

# 栈前进
tex // """
[
    1 over
    [0 over]
    [
        0
        2 swap
        1 swap
        0 swap
        1 -
    ]
    while-do
    drop

    0 0 swap
    1 swap 2 + 1 swap
    0 swap 2 + 0 swap
    [0 over]
    [
        2 over 1 + over
        2 over 1 + swap
        3 over 1 + swap
        drop
        1 -
        0 swap 1 + 0 swap
        1 swap 1 + 1 swap
    ]
    while-do
    drop
    drop
    drop
]
1 2 3

7 4
2 3 + over call

"""

# 栈后退
tex // """
0 0 0 0 0 0 0
[
    1 over 0 swap
    0 over
    1 swap 3 + 1 over + 1 swap
    0 swap 3 + 0 swap
    [0 over]
    [
        2 over over
        2 over swap
        3 over swap
        drop
        1 -
        0 swap 1 - 0 swap
        1 swap 1 - 1 swap
    ]
    while-do
    drop
    drop
    drop

    [0 over]
    [
        0 swap
        drop
        1 -
    ]
    while-do
    drop
]
1 2 3

7 4
2 3 + over call

"""

# 目前用到了7位over和swap
over1 = "dump over load swap"
over2 = "dump dump over load swap load swap"
over3 = "dump dump dump over load swap load swap load swap"
over4 = "dump dump dump dump over load swap load swap load swap load swap"
over5 = "dump dump dump dump dump over load swap load swap load swap load swap load swap"
over6 = "dump dump dump dump dump dump over load swap load swap load swap load swap load swap load swap"
over7 = "dump dump dump dump dump dump dump over load swap load swap load swap load swap load swap load swap load swap"
swap1 = "swap dump swap load swap"
swap2 = "swap dump swap dump swap load swap load swap"
swap3 = "swap dump swap dump swap dump swap load swap load swap load swap"
swap4 = "swap dump swap dump swap dump swap dump swap load swap load swap load swap load swap"
swap5 = "swap dump swap dump swap dump swap dump swap dump swap load swap load swap load swap load swap load swap"
swap6 = "swap dump swap dump swap dump swap dump swap dump swap dump swap load swap load swap load swap load swap load swap load swap"
swap7 = "swap dump swap dump swap dump swap dump swap dump swap dump swap dump swap load swap load swap load swap load swap load swap load swap load swap"
muln2 = 'over +'
muln3 = 'over over + +'
muln4 = 'over + over +'
lt3 = '- / over [drop 1] if'
ge3 = '- / over [drop 1] if 1 swap -'
gt3 = 'swap - / over [drop 1] if'
le3 = 'swap - / over [drop 1] if 1 swap -'
max3 = f'{over1} {over1} {lt3} [swap]if drop'
min3 = f'{over1} {over1} {ge3} [swap]if drop'
bool4 = 'over [drop 1]if'
and4 = f'0 {swap1} [+][drop]if-else'
or4 = f'{over1} [drop][swap drop]if-else'
not4 = 'over [drop 1]if 1 swap -'
eq4 = f'- {not4}'
ne4 = f'- {bool4}'




swap22 = f'{swap1} swap {swap2} swap'
tex // f'1 2 3 4 {swap22}'
swap12 = f'swap {swap1}'
tex // f'1 2 3 {swap12}'
swap21 = f'{swap1} swap'
tex // f'1 2 3 {swap21}'
swap31 = f'{swap2} {swap1} swap'
tex // f'1 2 3 4 {swap31}'
swap13 = f'swap {swap1} {swap2}'
tex // f'1 2 3 4 {swap13}'
swap_ = f'swap {swap1} swap'
#swap_ = '1 swap 0 swap 1 swap'
tex // f'1 2 3 {swap_}'
swap__ = f'{swap1} {swap2} {swap1}'
tex // f'1 2 3 4 {swap__}'

lt4 = f'''
swap
over / over {swap21} -
{swap12}
over / over {swap21} -
{swap__} {swap21}
{over1} {over1} {eq4}
[
  drop drop {lt3}
]
[
  {bool4} {swap2} drop drop drop
]
if-else
'''


tex // f'9 1 {lt4}'
tex // f'e f {lt4}'
tex // f'a a {lt4}'

gt4 = f'''
swap
over / over {swap21} -
{swap12}
over / over {swap21} -
{swap__} {swap21}
{over1} {over1} {eq4}
[
  drop drop {gt3}
]
[
  drop {bool4} {swap1} drop drop
]
if-else
'''

tex // f'a 9 {gt4}'
tex // f'a a {gt4}'
tex // f'e f {gt4}'

le4 = f'''
swap
over / over {swap21} -
{swap12}
over / over {swap21} -
{swap__} {swap21}
{over1} {over1} {eq4}
[
  drop drop {le3}
]
[
  {bool4} {swap2} drop drop drop
]
if-else
'''

tex // f'9 1 {le4}'
tex // f'e f {le4}'
tex // f'e e {le4}'


ge4 = f'''
swap
over / over {swap21} -
{swap12}
over / over {swap21} -
{swap__} {swap21}
{over1} {over1} {eq4}
[
  drop drop {ge3}
]
[
  drop {bool4} {swap1} drop drop
]
if-else
'''

tex // f'a 9 {ge4}'
tex // f'a a {ge4}'
tex // f'e f {ge4}'



#4位乘法（乘数，乘数）（结果）
mul4 = f'''

  0
  {over1} /
    [
      {over2} +
    ]
    if
    over +
    swap over + swap
    {over1} /
    [
      {over2} +
    ]
    if
    over +
    swap over + swap
    {over1} /
    [
      {over2} +
    ]
    if
    over +
    swap over + swap
    {over1} /
    [
      {over2} +
    ]
    if
    {swap1} drop drop
'''

tex // f'3 3 {mul4} 2 2 {mul4} +'        # 计算 3 和 2的平方和


# 4位全加器 （进位，加数，加数）（高位，低位）
add_part = f'''

  {over1} / {over2} {over1} -
  {swap2} drop
  {over1} / {over2} {over1} -
  {swap2} drop
  {over3} {over3} +
  over / {over1} {over1} -
  {swap1} drop
  {swap3} drop
  {swap3} drop
  0
  swap [1 +] if
  swap [1 +] if
  swap [1 +] if
  over + over +
  over /
  [1][0]if-else
  swap over +
  {over2} +
  swap {swap1} drop
  swap {swap1}
  [
    over f -
    [1 +]
    [drop drop 1 0]
    if-else
  ]
  if

'''

tex // f'1 8 9 {add_part}'

# (ah, al, bh, bl) (rh, rl)
add8 = f'''
  {swap_}
  0 {swap21} {add_part}
  swap
  {swap22} {add_part}
  swap drop swap
'''

tex // f'1 f 1 f {add8}'
tex // f'3 2 4 e {add8}'


shift8 = '''
swap over + swap
over /
[swap 1 + swap]
if
over +
'''

tex // f'0 f {shift8} {shift8}'

# 88乘法 （ah，al, bh, bl）（rh，rl）
mul8 = f'''
  0 0
  {over5} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over5} over + {swap5} drop
  {shift8}
  {over5} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over5} over + {swap5} drop
  {shift8}
  {over5} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over5} over + {swap5} drop
  {shift8}
  {over5} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over5} over + {swap5} drop
  {shift8}
  {over4} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over4} over + {swap4} drop
  {shift8}
  {over4} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over4} over + {swap4} drop
  {shift8}
  {over4} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over4} over + {swap4} drop
  {shift8}
  {over4} /
  [
    {over3}  {over3} {add8}
  ]
  if
  {over4} over + {swap4} drop

  {swap3} drop {swap3} drop drop drop


'''

tex // f'f 0 0 1 {mul8}'
tex // f'2 0 0 2 {mul8}'
tex // f'0 f 0 f {mul8}'

'''
ah al bh bl 0 0
5  4  3  2  1 0
'''

sub8 = f'''
f {over2} - f {over2} -
{swap1} drop {swap1} drop
over f {eq4}
[swap 1 + swap]
if
1 +
{add8}

'''
tex // f'1 4 0 f {sub8}'


eq8 = f'''
{swap_}
{eq4} {swap21} {eq4}
{and4}
'''
tex // f'f 3 f 3 {eq8}'

ne8 = f'''
{swap_}
{ne4} {swap21} {ne4}
{or4}
'''
tex // f'f 3 e 2 {ne8}'

lt8 = f'''
{swap_} {swap22}
{over1} {over1} {eq4}
[
  drop drop {lt4}
]
[
  {lt4} {swap1} drop drop
]
if-else
'''

tex // f'2 8 1 9 {lt8}'

gt8 = f'''
{swap_} {swap22}
{over1} {over1} {eq4}
[
  drop drop {gt4}
]
[
  {gt4} {swap1} drop drop
]
if-else
'''

tex // f'2 8 1 9 {gt8}'

le8 = f'''
{swap_} {swap22}
{over1} {over1} {eq4}
[
  drop drop {le4}
]
[
  {lt4} {swap1} drop drop
]
if-else
'''

tex // f'2 8 1 9 {le8}'

ge8 = f'''
{swap_} {swap22}
{over1} {over1} {eq4}
[
  drop drop {ge4}
]
[
  {gt4} {swap1} drop drop
]
if-else
'''

tex // f'2 8 2 8 {ge8}'



# (a, b, r, s)
div4 = f'''
0 0
{over3} / {bool4} +
{swap2} {muln2} {swap2}
{over2} {over1} {le4}
[
  swap 1 + swap
    {over2} -
]
if
{muln2}
swap {muln2} swap
{over3} / {bool4} +
{swap2} {muln2} {swap2}
{over2} {over1} {le4}
[
  swap 1 + swap
    {over2} -
]
if
{muln2}
swap {muln2} swap
{over3} / {bool4} +
{swap2} {muln2} {swap2}
{over2} {over1} {le4}
[
  swap 1 + swap
    {over2} -
]
if
{muln2}
swap {muln2} swap
{over3} / {bool4} +
{swap2} {muln2} {swap2}
{over2} {over1} {le4}
[
  swap 1 + swap
    {over2} -
]
if
{swap22} drop drop

'''

tex // f'f 2 {div4}'
tex // f'd 3 {div4}'

swapd0 = swap22

swapd1 = f'{swap4} swap {swap4} {swap3}'
tex // f'1 2 3 4 5 6 {swapd1}'

swapd2 = f'{swap6} swap {swap6} {swap5}'
tex // f'1 2 3 4 5 6 7 8 {swapd2}'


muldn2 = f'{over1} {over1} {add8}'

overd2 = f'{over5} {over5}'
overd1 = f'{over3} {over3}'

# (ah, al, bh, bl, rh, rl, sh, sl)
div8 = f'''
0 0 0 0
{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if

{muldn2}
{swapd0} {muldn2} {swapd0}

{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if

{muldn2}
{swapd0} {muldn2} {swapd0}

{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if

{muldn2}
{swapd0} {muldn2} {swapd0}

{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if




{muldn2}
{swapd0} {muldn2} {swapd0}

{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if

{muldn2}
{swapd0} {muldn2} {swapd0}

{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if

{muldn2}
{swapd0} {muldn2} {swapd0}

{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if

{muldn2}
{swapd0} {muldn2} {swapd0}

{over7} / {bool4} 0 swap {add8}
{swapd2} {muldn2} {swapd2}
{overd2} {overd1} {le8}
[
  {swapd0}  0 1 {add8} {swapd0}
    {overd2} {sub8}
]
if

{swapd1} drop drop {swapd1} drop drop



'''



main()


